import 'dart:async';

import 'package:flutter/material.dart';
import 'package:flutter_blue_plus/flutter_blue_plus.dart';

void main() {
  runApp(const MyApp());
}

class MyApp extends StatelessWidget {
  const MyApp({super.key});

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Bluetooth Demo',
      theme:
          ThemeData(primarySwatch: Colors.green, colorScheme: ColorScheme.fromSeed(seedColor: Colors.green)),
      home: const BluetoothScreen(),
    );
  }
}

class BluetoothScreen extends StatefulWidget {
  const BluetoothScreen({super.key});

  @override
  State<BluetoothScreen> createState() => _BluetoothScreenState();
}

class _BluetoothScreenState extends State<BluetoothScreen> {
  List<ScanResult> _scanResults = [];
  BluetoothDevice? _connectedDevice;
  List<BluetoothService> _services = [];
  BluetoothCharacteristic? _writeCharacteristic;
  final TextEditingController _messageController = TextEditingController();
  final List<String> _receivedMessages = [];

  bool _isScanning = false;
  bool _isConnecting = false;

  BluetoothAdapterState? adapterState;

  final FocusNode _inputFocusNode = FocusNode();

  @override
  void initState() {
    super.initState();
    _watchBluetoothAdapter();
    _setupScanListeners();
  }

  void _watchBluetoothAdapter() {
    FlutterBluePlus.setLogLevel(LogLevel.verbose, color:false);

    List<BluetoothDevice> devs = FlutterBluePlus.connectedDevices;
    for (var d in devs) {
      print("======= $d");
    }

    FlutterBluePlus.adapterState.listen((state) {
      if (!mounted) {
        return;
      }
      setState(() {
        adapterState = state;
      });
    });
  }

  void _setupScanListeners() {
    FlutterBluePlus.setOptions(restoreState: true);
    final subscription = FlutterBluePlus.scanResults.listen((results) {
      Set<String> seenDeviceIds = {};
      List<ScanResult> uniqueResults = results.where((result) {
        return seenDeviceIds.add(result.device.remoteId.str);
      }).toList();

      setState(() => _scanResults = uniqueResults);
    });
    FlutterBluePlus.cancelWhenScanComplete(subscription);
  }

  Future<void> _startScan() async {
    setState(() => _isScanning = true);
    await FlutterBluePlus.startScan(
        continuousUpdates: true,
        // withNames: ["L Service"],
        withServices: [Guid("A07498CA-AD5B-474E-940D-16F1FBE7E8CD")],
        removeIfGone: Duration(seconds: 10),
        timeout: const Duration(seconds: 12));
    setState(() => _isScanning = false);
  }

  Future<void> _stopScan() async {
    await FlutterBluePlus.stopScan();
    setState(() => _isScanning = false);
  }

  Future<void> _connectToDevice(BluetoothDevice device) async {
    if (_connectedDevice != null && _connectedDevice!.remoteId == device.remoteId) {
      print("断开连接");
      // If the device is already connected, disconnect it
      await _connectedDevice!.disconnect();
      setState(() {
        _connectedDevice = null;
        _services.clear();
        _writeCharacteristic = null;
        _receivedMessages.clear();
      });
      print("连接已断开");
      setState(() {
        _isConnecting = false;
      });
    } else {
      if (_isConnecting) {
        return;
      }
      print("开始连接");
      setState(() {
        _isConnecting = true;
      });
      // Otherwise, connect to the device
      await _stopScan();
      try {
        await device.connect();
        setState(() => _connectedDevice = device);
        print("连接成功");
      } catch (e) {
        print("连接失败: $e");
        return;
      } finally {
        setState(() {
          _isConnecting = false;
        });
      }

      List<BluetoothService> services = await device.discoverServices();
      for (var service in services) {
        print("服务: $service");
        for (var characteristic in service.characteristics) {
          print("特征值: $characteristic");
          if (characteristic.properties.write &&
              characteristic.characteristicUuid.str.toUpperCase() == "2340E20F-BB64-40B1-B229-BBF3C2637ADC") {
            _writeCharacteristic = characteristic;
          }
          if ((characteristic.properties.notify || characteristic.properties.indicate) &&
              characteristic.characteristicUuid.str.toUpperCase() == "51FF12BB-3ED8-46E5-B4F9-D64E2FEC021B") {
            final subscription = characteristic.onValueReceived.listen((value) {
              if (value.isNotEmpty) {
                String message = String.fromCharCodes(value);
                setState(() => _receivedMessages.add(message));
              }
            });
            device.cancelWhenDisconnected(subscription);
            await characteristic.setNotifyValue(true);
          }
        }
      }
      setState(() => _services = services);
    }
  }

  Future<void> _sendMessage(String message) async {
    if (_writeCharacteristic == null || message.isEmpty) return;

    List<int> bytes = message.codeUnits;
    await _writeCharacteristic!.write(bytes);
    _messageController.clear();
    _inputFocusNode.unfocus();
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: const Text('Bluetooth Demo')),
      body: GestureDetector(
        onTap: () {
          _inputFocusNode.unfocus();
        },
        child: SafeArea(
          child: Column(
            children: [
              Expanded(
                child: ListView(
                  padding: const EdgeInsets.all(16.0),
                  children: [
                    // 控制按钮
                    Row(
                      mainAxisAlignment: MainAxisAlignment.spaceEvenly,
                      children: [
                        TextButton(
                          onPressed: _isScanning ? null : _startScan,
                          child: Text('扫描设备（${_scanResults.length}）'),
                        )
                      ],
                    ),

                    // 设备列表
                    Container(
                      height: 68,
                      decoration: BoxDecoration(border: Border.all(color: Colors.green)),
                      child: ListView.builder(
                        padding: EdgeInsets.symmetric(horizontal: 5, vertical: 5),
                        itemCount: _scanResults.length,
                        itemBuilder: (context, index) {
                          ScanResult result = _scanResults[index];
                          bool isConnected = _connectedDevice != null &&
                              _connectedDevice!.remoteId == result.device.remoteId;
                          return ListTile(
                            title: Text(result.device.platformName.isNotEmpty
                                ? result.device.platformName
                                : result.device.remoteId.str),
                            trailing: ElevatedButton(
                                style: ElevatedButton.styleFrom(
                                  backgroundColor: Colors.black,
                                  foregroundColor: Colors.white,
                                ),
                                onPressed: _isConnecting ? null : () => _connectToDevice(result.device),
                                child: Text(_isConnecting
                                    ? "正在连接"
                                    : isConnected
                                        ? "已连接"
                                        : "连接")),
                            tileColor: isConnected ? Colors.green[100] : null,
                            onTap: () => _connectToDevice(result.device),
                          );
                        },
                      ),
                    ),

                    // 连接状态
                    if (_connectedDevice != null)
                      Padding(
                        padding: const EdgeInsets.symmetric(vertical: 8.0),
                        child: Text(
                          '已连接: ${_connectedDevice!.platformName}',
                          style: const TextStyle(fontSize: 16),
                        ),
                      ),

                    // 接收消息
                    Container(
                      margin: EdgeInsets.only(top: 20, bottom: 5),
                      child: Row(
                        mainAxisAlignment: MainAxisAlignment.start,
                        children: [
                          Text('收到消息:'),
                        ],
                      ),
                    ),
                    Container(
                      height: 200,
                      decoration: BoxDecoration(border: Border.all(color: Colors.green)),
                      child: ListView.builder(
                        itemCount: _receivedMessages.length,
                        itemBuilder: (context, index) {
                          return ListTile(
                            title: Text(_receivedMessages[index]),
                          );
                        },
                      ),
                    ),
                  ],
                ),
              ),

              // 消息输入
              Padding(
                padding: const EdgeInsets.all(8.0),
                child: Row(
                  children: [
                    Expanded(
                      child: TextField(
                        focusNode: _inputFocusNode,
                        controller: _messageController,
                        decoration: InputDecoration(
                          contentPadding: const EdgeInsets.symmetric(vertical: 10.0, horizontal: 10.0),
                          isCollapsed: true,
                          filled: true,
                          fillColor: Colors.white,
                          enabledBorder: OutlineInputBorder(
                            borderSide: BorderSide(color: Color(0xFFEBECF0)),
                            borderRadius: BorderRadius.circular(10),
                          ),
                          focusedBorder: OutlineInputBorder(
                            borderSide: BorderSide(color: Color(0xFFEBECF0)),
                            borderRadius: BorderRadius.circular(10),
                          ),
                        ),
                      ),
                    ),
                    IconButton(
                      icon: const Icon(Icons.send),
                      onPressed:
                          _connectedDevice == null ? null : () => _sendMessage(_messageController.text),
                    ),
                  ],
                ),
              ),
            ],
          ),
        ),
      ),
    );
  }

  @override
  void dispose() {
    FlutterBluePlus.stopScan();
    _connectedDevice?.disconnect();
    super.dispose();
  }
}
